package com.scut.fy.common.core.util;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.springframework.cglib.beans.BeanMap;
import org.springframework.objenesis.instantiator.util.ClassUtils;
import org.springframework.util.CollectionUtils;

import javax.annotation.Nullable;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * TODO
 *
 * @author JY
 * @version 1.0
 * @date 2021/9/6
 */
public class BeanUtils {
    private BeanUtils(){};

    /**
     * beanToMap
     * @param bean
     * @return
     */
    public static Map<String, Object> beanToMap(@Nullable Object bean) {
        return null == bean ? null : BeanMap.create(bean);
    }

    /**
     * mapToBean
     * @param map
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T mapToBean(@Nullable Map<String, ?> map, Class<T> clazz) {
        T bean = ClassUtils.newInstance(clazz);
        BeanMap.create(bean).putAll(map);
        return bean;
    }

    /**
     * beansToMaps
     * @param beans
     * @param <T>
     * @return
     */
    public static <T> List<Map<String, Object>> beansToMaps(@Nullable List<T> beans) {
        if (CollectionUtils.isEmpty(beans)) {
            return Collections.emptyList();
        }
        return beans.stream().map(BeanUtils::beanToMap).collect(Collectors.toList());
    }

    /**
     * mapsToBeans
     * @param maps
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> List<T> mapsToBeans(@Nullable List<? extends Map<String, ?>> maps, Class<T> clazz) {
        if (CollectionUtils.isEmpty(maps)) {
            return Collections.emptyList();
        }
        return maps.stream().map(e -> mapToBean(e, clazz)).collect(Collectors.toList());
    }

    /**
     * beanToJson
     * @param bean
     * @return String
     */
    public static JSONObject beanToJson(@Nullable Object bean) {
        return null == bean ? null : new JSONObject(BeanMap.create(bean));
    }

    /**
     * jsonToBean
     * @param json
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T jsonToBean(@Nullable String json, Class<T> clazz) {
        return null == json ? null : JSONObject.parseObject(json, clazz);
    }

    /**
     * beansToJsons
     * @param beans
     * @return
     */
    public static JSONArray beansToJsons(@Nullable List<Object> beans) {
        return CollectionUtils.isEmpty(beans) ? null : new JSONArray(beans);
    }

    /**
     * jsonsToBeans
     * @param json
     * @param clazz
     * @param <T>
     * @return
     */
    public <T> List<T> jsonsToBeans(@Nullable String json, Class<T> clazz) {
        return null == json ? null : JSONArray.parseArray(json, clazz);
    }

}
